/**
 * 
 */
package fr.gfi.agraf.vue.action.administrer.perimetre;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import fr.gfi.agraf.exception.AgrafException;
import fr.gfi.agraf.service.IActiviteService;
import fr.gfi.agraf.service.enumeration.EtatEnum;
import fr.gfi.agraf.utils.PropertiesUtils;
import fr.gfi.agraf.utils.SpringFactory;
import fr.gfi.agraf.utils.VerificationUtils;
import fr.gfi.agraf.vue.action.AbstractApplicationSupportAction;
import fr.gfi.agraf.vue.bean.ActiviteDTO;
import fr.gfi.agraf.vue.bean.EtatDTO;
import fr.gfi.agraf.vue.bean.PerimetreDTO;

/**
 * @author Fw
 * 
 */
public class ModifierPerimetreAction extends AbstractApplicationSupportAction {

	/**
	 * Logger
	 */
	private final static Logger LOGGER = Logger.getLogger(ModifierPerimetreAction.class);

	/**
	 * Généré par Java
	 */
	private static final long serialVersionUID = 3419958559224440852L;

	private static final String ACTIVITE_SERVICE = "ActiviteService";

	private static final String ERREUR_DONNEES_INCOHERENTE = "erreur.donnees.incoherente.modifier.perimetre";

	private static final String MESSAGE_MODIFICATION_OK = "modification.perimetre.ok";

	private Long idPerimetre;

	private String libellePerimetre;

	private Long[] idActivites;

	private String[] libellesActivites;

	private String[] libellesActivitesOld;

	private String[] remarquesActivites;

	private String[] remarquesActivitesOld;

	private List<Long> supprActivite;

	private String[] libellesNouvellesActivites;

	private String[] remarquesNouvellesActivites;

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * fr.gfi.agraf.vue.action.AbstractApplicationSupportAction#executeAction()
	 */
	@Override
	public String executeAction() throws Exception {
		final List<ActiviteDTO> listeActivitesModifiees = getActiviteToModifier();
		final List<ActiviteDTO> listeNouvellesActivites = getActiviteToAdd();

		final IActiviteService activiteService = (IActiviteService) SpringFactory.getApplicationContext()
				.getBean(ACTIVITE_SERVICE);

		try {
			activiteService.modifierPerimetreFromIHM(idPerimetre, libellePerimetre, supprActivite,
					listeActivitesModifiees, listeNouvellesActivites);
		} catch (final AgrafException e) {
			final String messageErreur = PropertiesUtils.getProperty(e.getKey());
			addActionError(messageErreur);
			LOGGER.error(messageErreur, e);
			return ERROR;
		}

		addActionMessage(PropertiesUtils.getProperty(MESSAGE_MODIFICATION_OK));
		return SUCCESS;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.opensymphony.xwork2.ActionSupport#validate()
	 */
	@Override
	public void validate() {
		if (libellePerimetre.isEmpty() || idPerimetre == null) {
			addActionError(PropertiesUtils.getProperty(ERREUR_DONNEES_INCOHERENTE));
			return;
		}

		if (!VerificationUtils.checkAreInputTabsOk(idActivites, libellesActivites, libellesActivitesOld,
				remarquesActivites, remarquesActivitesOld)) {
			addActionError(PropertiesUtils.getProperty(ERREUR_DONNEES_INCOHERENTE));
			return;
		}

		if (!VerificationUtils.checkAreInputTabsOk(libellesNouvellesActivites, remarquesNouvellesActivites)) {
			addActionError(PropertiesUtils.getProperty(ERREUR_DONNEES_INCOHERENTE));
			return;
		}
		super.validate();
	}

	/**
	 * Retourne la liste des activites à ajouter
	 * 
	 * @return
	 */
	private List<ActiviteDTO> getActiviteToAdd() {
		final List<ActiviteDTO> listeNouvellesActivites = new ArrayList<ActiviteDTO>();
		if (libellesNouvellesActivites != null) {
			for (int i = 0; i < libellesNouvellesActivites.length; i++) {
				listeNouvellesActivites.add(creerActiviteToAdd(i));
			}
		}
		return listeNouvellesActivites;
	}

	/**
	 * Retourne la liste des activites à modifier
	 * 
	 * @return
	 */
	private List<ActiviteDTO> getActiviteToModifier() {
		final List<ActiviteDTO> listeActivitesModifiees = new ArrayList<ActiviteDTO>();
		// Je crée les activitées à modifier
		int nbreActivite = 0;
		if (idActivites != null) {
			nbreActivite = idActivites.length;
		}
		for (int i = 0; i < nbreActivite; i++) {
			// Si l'activite itérée est à supprimer, je passe
			if (supprActivite != null && supprActivite.contains(idActivites[i])) {
				break;
			}
			if (isChanged(i)) {
				listeActivitesModifiees.add(creerActiviteToModifier(i));
			}
		}
		return listeActivitesModifiees;
	}

	/**
	 * Créer activiteDTO à ajouter
	 * 
	 * @param i
	 * @return
	 */
	private ActiviteDTO creerActiviteToAdd(final int i) {
		final ActiviteDTO activiteDTO = new ActiviteDTO();
		activiteDTO.setDateCreation(new Date());
		final EtatDTO etat = new EtatDTO();
		etat.setId(EtatEnum.CREE.getId());
		activiteDTO.setEtat(etat);
		activiteDTO.setLibelle(libellesNouvellesActivites[i]);
		activiteDTO.setRemarque(remarquesNouvellesActivites[i]);
		final PerimetreDTO perimetreDTO = new PerimetreDTO();
		perimetreDTO.setId(idPerimetre);
		activiteDTO.setPerimetre(perimetreDTO);
		return activiteDTO;
	}

	/**
	 * Créer activiteDTO à modifier
	 * 
	 * @param i
	 * @return
	 */
	private ActiviteDTO creerActiviteToModifier(final int i) {
		final ActiviteDTO activiteDTO = new ActiviteDTO();
		activiteDTO.setId(idActivites[i]);
		activiteDTO.setLibelle(libellesActivites[i]);
		activiteDTO.setRemarque(remarquesActivites[i]);
		return activiteDTO;
	}

	/**
	 * Retourne true s'il y a eu un changement
	 * 
	 * @param i
	 * @return
	 */
	private boolean isChanged(final int i) {
		if (!StringUtils.equals(libellesActivites[i], libellesActivitesOld[i])) {
			return true;
		}
		if (!StringUtils.equals(remarquesActivites[i], remarquesActivitesOld[i])) {
			return true;
		}
		return false;
	}

	/**
	 * @return the libellePerimetre
	 */
	public String getLibellePerimetre() {
		return libellePerimetre;
	}

	/**
	 * @param libellePerimetre
	 *            the libellePerimetre to set
	 */
	public void setLibellePerimetre(final String libellePerimetre) {
		this.libellePerimetre = libellePerimetre;
	}

	/**
	 * @return the libellesActivites
	 */
	public String[] getLibellesActivites() {
		return libellesActivites;
	}

	/**
	 * @param libellesActivites
	 *            the libellesActivites to set
	 */
	public void setLibellesActivites(final String[] libellesActivites) {
		this.libellesActivites = libellesActivites;
	}

	/**
	 * @return the libellesActivitesOld
	 */
	public String[] getLibellesActivitesOld() {
		return libellesActivitesOld;
	}

	/**
	 * @param libellesActivitesOld
	 *            the libellesActivitesOld to set
	 */
	public void setLibellesActivitesOld(final String[] libellesActivitesOld) {
		this.libellesActivitesOld = libellesActivitesOld;
	}

	/**
	 * @return the remarquesActivites
	 */
	public String[] getRemarquesActivites() {
		return remarquesActivites;
	}

	/**
	 * @param remarquesActivites
	 *            the remarquesActivites to set
	 */
	public void setRemarquesActivites(final String[] remarquesActivites) {
		this.remarquesActivites = remarquesActivites;
	}

	/**
	 * @return the remarquesActivitesOld
	 */
	public String[] getRemarquesActivitesOld() {
		return remarquesActivitesOld;
	}

	/**
	 * @param remarquesActivitesOld
	 *            the remarquesActivitesOld to set
	 */
	public void setRemarquesActivitesOld(final String[] remarquesActivitesOld) {
		this.remarquesActivitesOld = remarquesActivitesOld;
	}

	/**
	 * @return the idActivites
	 */
	public Long[] getIdActivites() {
		return idActivites;
	}

	/**
	 * @param idActivites
	 *            the idActivites to set
	 */
	public void setIdActivites(final Long[] idActivites) {
		this.idActivites = idActivites;
	}

	/**
	 * @return the supprActivite
	 */
	public List<Long> getSupprActivite() {
		return supprActivite;
	}

	/**
	 * @param supprActivite
	 *            the supprActivite to set
	 */
	public void setSupprActivite(final List<Long> supprActivite) {
		this.supprActivite = supprActivite;
	}

	/**
	 * @return the idPerimetre
	 */
	public Long getIdPerimetre() {
		return idPerimetre;
	}

	/**
	 * @param idPerimetre
	 *            the idPerimetre to set
	 */
	public void setIdPerimetre(final Long idPerimetre) {
		this.idPerimetre = idPerimetre;
	}

	/**
	 * @return the libellesNouvellesActivites
	 */
	public String[] getLibellesNouvellesActivites() {
		return libellesNouvellesActivites;
	}

	/**
	 * @param libellesNouvellesActivites
	 *            the libellesNouvellesActivites to set
	 */
	public void setLibellesNouvellesActivites(final String[] libellesNouvellesActivites) {
		this.libellesNouvellesActivites = libellesNouvellesActivites;
	}

	/**
	 * @return the remarquesNouvellesActivites
	 */
	public String[] getRemarquesNouvellesActivites() {
		return remarquesNouvellesActivites;
	}

	/**
	 * @param remarquesNouvellesActivites
	 *            the remarquesNouvellesActivites to set
	 */
	public void setRemarquesNouvellesActivites(final String[] remarquesNouvellesActivites) {
		this.remarquesNouvellesActivites = remarquesNouvellesActivites;
	}

}
